package com.frcdi.qms.common.utils.sql;

import cn.hutool.core.io.resource.ClassPathResource;
import cn.hutool.system.SystemUtil;

import java.io.*;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Logger;

public class MysqlBackupUtils {

    /**
     * @param hostIP       ip地址，可以是本机也可以是远程
     * @param userName     数据库的用户名
     * @param password     数据库的密码
     * @param savePath     备份的路径
     * @param fileName     备份的文件名
     * @param databaseName 需要备份的数据库的名称
     * @return
     */
    public static boolean backup(String hostIP, String userName, String password,
                                 String savePath, String fileName, String databaseName,String port) {
        File saveFile = new File(savePath);
        if (!saveFile.exists()) {// 如果目录不存在
            saveFile.mkdirs();// 创建文件夹
        }
        if (!savePath.endsWith(File.separator)) {
            savePath = savePath + File.separator;
        }
        StringBuilder stringBuilder = new StringBuilder();
        String os = SystemUtil.getOsInfo().getName();
        if (os.indexOf("Windows") >= 0) {
            //windows
            //拼接命令行的命令
//            stringBuilder.append("mysqldump").append(" --defaults-extra-file=D:\\Java\\mysql\\Data\\my.ini").append(" --opt").append(" -h").append(hostIP);
//            stringBuilder.append(" --lock-all-tables=true").append(" --result-file=").append(savePath + fileName)
//                    .append(" --default-character-set=utf8 ")
//                    .append(databaseName);
           stringBuilder.append("mysqldump").append(" --opt").append(" -h ").append(hostIP);
            stringBuilder.append(" --user=").append(userName).append(" --password=").append(password);
            stringBuilder.append(" -P").append(port);
            stringBuilder.append(" --lock-all-tables=true").append(" --result-file=").append(savePath + fileName)
                    .append(" --default-character-set=utf8 ")
                    .append(databaseName);
        } else {
            //linux
            //拼接命令行的命令
           stringBuilder.append("mysqldump").append(" -h ").append(hostIP);
            stringBuilder.append(" -u").append(userName).append(" -p").append(password).append(" -P").append(port).append(" ")
                    .append(databaseName).append(" -r").append(savePath + fileName);
        }
        try {
            //调用外部执行exe文件的javaAPI
            String s = stringBuilder.toString();
            Process process = Runtime.getRuntime().exec(s);
            System.out.println(s);
            if (process.waitFor() == 0) {// 0 表示线程正常终止
                return true;
            }
        } catch (IOException e) {
            e.printStackTrace();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return false;
    }

    /**
     * @param filepath 数据库备份的脚本路径
     * @param ip       IP地址
     * @param database 数据库名称
     * @param userName 用户名
     * @param password 密码
     * @return
     */
    public static boolean recover(String filepath, String ip, String database, String userName, String password,String port) {
        String os = SystemUtil.getOsInfo().getName();
        if (os.indexOf("Windows") >= 0) {
            ProcessBuilder processBuilder = new ProcessBuilder();
            processBuilder.redirectErrorStream(true);
            try {
                //恢复数据
                List<String> recoverCommands = new ArrayList<>();
                recoverCommands.add("cmd");
                recoverCommands.add("/c");
                recoverCommands.add("mysql");
                recoverCommands.add(" -h" + ip);
                recoverCommands.add(" -u" + userName);
                recoverCommands.add(" -p" + password);
                recoverCommands.add(" -P" + port);
                recoverCommands.add(" " +database);
                recoverCommands.add("<");
                recoverCommands.add(filepath);
                processBuilder.command(recoverCommands);
                //
                Process recoverProcess = processBuilder.start();
                new CleanInputCatche(recoverProcess.getInputStream()).start();
                recoverProcess.waitFor();
            } catch (Exception e) {
                e.printStackTrace();
                return false;
            }
            return true;
        } else {
            //linux
            String stmt1 = "mysqladmin -h " + ip + " -u " + userName + " -p" + password + " create " + database;
            String stmt2 = "mysql -h " + ip + " -u " + userName + " -p " + password +" -P" + port + " " + database + " < " + filepath;
            String[] cmd = {"cmd", "/c", stmt2};
            try {
                Runtime.getRuntime().exec(stmt1);
                Runtime.getRuntime().exec(cmd);
            } catch (IOException e) {
                e.printStackTrace();
                return false;
            }
            return true;
        }
    }

    //增量备份
    public static void incrementalBackup() {
        String os = SystemUtil.getOsInfo().getName();
        if (os.indexOf("Windows") >= 0) {
            //windows
            ClassPathResource classPathResource = new ClassPathResource("Incremental_backup.bat");
            String batPath = classPathResource.getAbsolutePath(); // 把你的bat脚本路径写在这里
            File batFile = new File(batPath);
            boolean batFileExist = batFile.exists();
            if (batFileExist) {
                callCmd(batPath);
            }
        } else {
            //linux
        }
    }

    // 执行bat脚本
    private static void callCmd(String locationCmd) {
        StringBuilder sb = new StringBuilder();
        try {
            Process child = Runtime.getRuntime().exec(locationCmd);
            InputStream in = child.getInputStream();
            BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(in));
            String line;
            while ((line = bufferedReader.readLine()) != null) {
                sb.append(line).append("\n");
            }
            in.close();
            try {
                child.waitFor();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
